home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / MotifApp / ch12 / Stage.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  5.8 KB  |  251 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //////////////////////////////////////////////////////////////////////////////
  3. //         This example code is from the book:
  4. //
  5. //           Object-Oriented Programming with C++ and OSF/Motif
  6. //         by
  7. //           Douglas Young
  8. //           Prentice Hall, 1992
  9. //           ISBN 0-13-630252-1    
  10. //
  11. //         Copyright 1991 by Prentice Hall
  12. //         All Rights Reserved
  13. //
  14. //  Permission to use, copy, modify, and distribute this software for 
  15. //  any purpose except publication and without fee is hereby granted, provided 
  16. //  that the above copyright notice appear in all copies of the software.
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20.  
  21. //////////////////////////////////////////////////////////
  22. // Stage.C
  23. //////////////////////////////////////////////////////////
  24. #include "Application.h"
  25. #include "Stage.h"
  26. #include "Actor.h"
  27. #include <Xm/DrawingA.h>
  28.  
  29. Stage::Stage ( Widget parent, char *name ) : UIComponent( name )
  30. {
  31.     XGCValues  gcv;
  32.     
  33.     // Initialize all data members 
  34.     
  35.     _front   = NULL;
  36.     _back    = NULL;
  37.     _nActors = 0;       
  38.     _cast    = NULL;
  39.     
  40.     // Create the visible drawing canvas, and set 
  41.     // up the destruction handler
  42.     
  43.     _w =  XtCreateWidget ( _name, 
  44.               xmDrawingAreaWidgetClass,
  45.               parent,
  46.               NULL, 0 );
  47.     
  48.     installDestroyHandler();
  49.     
  50.     // Add callbacks to handle resizing and exposures
  51.     
  52.     XtAddCallback ( _w, XmNresizeCallback, 
  53.            &Stage::resizeCallback,    
  54.            (XtPointer) this );
  55.     XtAddCallback ( _w, XmNexposeCallback, 
  56.            &Stage::redisplayCallback, 
  57.            (XtPointer) this );
  58.     
  59.     // A graphics context is need for copying the pixmap buffers and
  60.     // erasing the back pixmap. Use the background color of 
  61.     // the base widget for the fill color.
  62.     
  63.     XtVaGetValues ( _w, 
  64.            XmNbackground, &gcv.foreground,
  65.            NULL );
  66.     
  67.     _gc = XtGetGC ( _w, GCForeground, &gcv ); 
  68.     
  69.     // Call resize to create the first pixmaps.
  70.     
  71.     resize();
  72. }
  73.  
  74. Stage::~Stage()
  75. {
  76.     // Free the pixmaps and GC, if they still exist
  77.     
  78.     if ( _front )       
  79.     XFreePixmap ( XtDisplay ( _w ), _front );
  80.     
  81.     if ( _back )        
  82.     XFreePixmap ( XtDisplay ( _w ), _back );
  83.     
  84.     if ( _w && _gc )
  85.     XtReleaseGC ( _w, _gc );
  86. }
  87.  
  88. void Stage::resizeCallback ( Widget, 
  89.                 XtPointer clientData, 
  90.                 XtPointer )
  91. {
  92.     Stage *obj = (Stage *) clientData;
  93.     obj->resize();
  94. }    
  95.  
  96. void Stage::resize()
  97. {
  98.     // Get the current size of the drawing area
  99.     
  100.     XtVaGetValues ( _w, 
  101.            XmNwidth,  &_width,
  102.            XmNheight, &_height,
  103.            NULL );
  104.     
  105.     // Pixmaps can't be resized, so just destroy the old ones
  106.     
  107.     if ( _front )       
  108.     XFreePixmap ( XtDisplay ( _w ), _front );
  109.     
  110.     if ( _back )        
  111.     XFreePixmap ( XtDisplay ( _w ), _back );
  112.     
  113.     // Create new pixmaps to match the new size of the window
  114.     
  115.     _back = XCreatePixmap ( XtDisplay ( _w ),
  116.                DefaultRootWindow ( XtDisplay ( _w ) ),
  117.                _width, _height, 
  118.                DefaultDepthOfScreen ( XtScreen ( _w ) ) );
  119.     
  120.     _front = XCreatePixmap ( XtDisplay ( _w ),
  121.                 DefaultRootWindow ( XtDisplay ( _w ) ),
  122.                 _width, _height, 
  123.                 DefaultDepthOfScreen ( XtScreen ( _w ) ) );
  124.     
  125.     // Erase both pixmaps
  126.     
  127.     XFillRectangle ( XtDisplay ( _w ), _back, 
  128.             _gc, 0, 0, _width, _height );
  129.     XFillRectangle ( XtDisplay ( _w ), _front, 
  130.             _gc, 0, 0, _width, _height );
  131. }
  132.  
  133. void  Stage::nextFrame()
  134. {
  135.     // For each new frame, simply swap buffers and
  136.     // ask each Actor object to draw its next frame 
  137.     // in the back buffer.
  138.     
  139.     swapBuffers();
  140.     
  141.     for ( int i = 0; i < _nActors; i++)
  142.     _cast[i]->nextFrame ( _back, _width, _height );
  143. }
  144.  
  145. void Stage::swapBuffers()
  146. {
  147.     // Switch the front and back buffers
  148.     
  149.     if ( XtIsRealized ( _w ) )
  150.     {
  151.     Pixmap tmp;
  152.     
  153.     // Do the swap
  154.     
  155.     tmp    = _front;
  156.     _front = _back;
  157.     _back  = tmp;
  158.     
  159.     // Copy the new fron buffer to the drawing area
  160.     
  161.     XCopyArea ( XtDisplay ( _w ), _front, XtWindow ( _w ),
  162.            _gc, 0, 0, _width, _height, 0, 0 );
  163.     
  164.     // Erase the new back buffer to get ready for the next scene
  165.     
  166.     XFillRectangle ( XtDisplay ( _w ), _back, 
  167.             _gc, 0, 0, _width, _height );
  168.     }
  169. }
  170.  
  171. void Stage::redisplayCallback ( Widget, 
  172.                    XtPointer clientData, 
  173.                    XtPointer )
  174. {
  175.     Stage *obj = (Stage *) clientData;
  176.     obj->redisplay();
  177. }    
  178.  
  179. void Stage::redisplay ( )
  180. {
  181.     // Copy the contents of the front pixmap
  182.     // to restore the window
  183.     
  184.     XCopyArea ( theApplication->display(), _front, 
  185.            XtWindow ( _w ), _gc, 0, 0, 
  186.            _width, _height, 0, 0 );
  187. }    
  188.  
  189. void Stage::addActor ( Actor *newActor )
  190. {
  191.     int i;
  192.     
  193.     Actor **newList;
  194.     
  195.     // Allocate a new list large enough to hold
  196.     // one more object
  197.     
  198.     newList = new Actor*[_nActors + 1];
  199.     
  200.     // Copy the old list to the new
  201.     
  202.     for ( i = 0; i < _nActors; i++ )
  203.     newList[i] = _cast[i];
  204.     
  205.     // Add the new object to the end of the list
  206.     
  207.     newList[_nActors] = newActor;
  208.     
  209.     // delete the old list and make _cast 
  210.     // point to the new list
  211.     
  212.     delete _cast;
  213.     _cast = newList;
  214.     
  215.     
  216.     _nActors++;
  217. }
  218.  
  219. void Stage::removeActor( Actor *oldActor )
  220. {
  221.     int     i, j;
  222.     Boolean found = FALSE;
  223.     Actor **newList;
  224.     
  225.     // remove the given Actor from the list
  226.     
  227.     for ( i = 0; i < _nActors; i++ )
  228.     if ( _cast[i] == oldActor )
  229.     {
  230.         found = TRUE;
  231.         for ( j = i; j < _nActors-1; j++ )
  232.         _cast[j] = _cast[j+1];
  233.         break;
  234.     }
  235.     
  236.     if ( !found )
  237.     return;
  238.     
  239.     _nActors--;
  240.     
  241.     // Allocate a new, smaller list
  242.     
  243.     newList = new Actor*[_nActors];
  244.     
  245.     for ( i = 0; i < _nActors; i++ )
  246.     newList[i] = _cast[i];
  247.     
  248.     delete _cast;
  249.     _cast = newList;
  250. }
  251.